package com.zwx.helloworld.calendar;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zwx.helloworld.pub.util.JsonUtils;
import com.zwx.helloworld.pub.util.LogUtils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;

public class CalendarUtils {

  static final Logger logger = LoggerFactory.getLogger(CalendarUtils.class);
  static final Map<Integer, SpecialCalendar> specialCalendarMap =
      getSpecialCalendar("calendar/specialCalendar.json");

  private static Map<Integer, SpecialCalendar> getSpecialCalendar(String fileName) {
    String fName = "calendar/specialCalendar.json";
    if (StrUtil.isNotBlank(fileName)) {
      fName = fileName;
    }
    Map<Integer, SpecialCalendar> map = new HashMap<Integer, SpecialCalendar>();
    try {
      String specialCalendarStr = FileUtil.readUtf8String(fName);
      logger.debug("specialCalendarStr:{}", specialCalendarStr);
      List<SpecialCalendar> list = JsonUtils.json2list(specialCalendarStr, SpecialCalendar.class);
      for (SpecialCalendar sc : list) {
        map.put(sc.getYear(), sc);
      }
      return map;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 检查是否特殊日期 0-非特殊日期，1-工作日，2-非工作日
   * 
   * @param date
   * @return
   */
  static int checkSpecitalCalendar(Calendar date) {
    if (specialCalendarMap == null) {
      return 0;
    }
    SpecialCalendar sc = specialCalendarMap.get(date.get(Calendar.YEAR));
    if (sc == null) {
      return 0;
    }
    Date checkDate = date.getTime();
    for (Date sd : sc.getWorkDates()) {
      if (checkDate.compareTo(sd) == 0) {
        return 1;
      }
    }
    for (Date sd : sc.getNonWorkDates()) {
      if (checkDate.compareTo(sd) == 0) {
        return 2;
      }
    }
    return 0;
  }

  /**
   * 检查是否工作日 0-非工作日，1-工作日
   * 
   * @param date
   * @return
   */
  static int checkWorkDate(Calendar date) {
    if (date == null) {
      return 0;
    }
    int specFlag = checkSpecitalCalendar(date);
    int dayInWeek = date.get(Calendar.DAY_OF_WEEK);
    int result = 0;
    if (specFlag == 0) {
      if (1 == dayInWeek || 7 == dayInWeek) {
        // 星期天是1，星期六是7
        result = 0;
      } else {
        result = 1;
      }
    } else {
      if (specFlag == 1) {
        result = 1;
      } else {
        result = 0;
      }
    }
    logger.info("date:{},result:{}, specFlag:{}, dayInWeek:{}", date.getTime(), result, specFlag, dayInWeek);
    return result;
  }

  public static long calcWorkDays(Date beginDate, Date endDate) {
    if (beginDate == null || endDate == null) {
      logger.error("beginDate or endDate is wrong! beginDate:{} endDate:{}", beginDate, endDate);
    }
    if (beginDate.after(endDate)) {
      logger.error("beginDate is later than endDate! beginDate:{}  endDate:{}", beginDate, endDate);
    }
    logger.info("beginDate:{}  endDate:{}", beginDate, endDate);
    Calendar currentCal = Calendar.getInstance();
    Calendar beginCal = Calendar.getInstance();
    Calendar endCal = Calendar.getInstance();
    currentCal.setTime(beginDate);
    beginCal.setTime(beginDate);
    endCal.setTime(endDate);
    logger.info("beginCal:{}  endCal:{} currentCal:{}", beginCal.getTime(), endCal.getTime(), currentCal.getTime());
    long workDays = 0;
    while(currentCal.compareTo(endCal)<=0) {      
      workDays += checkWorkDate(currentCal);
      currentCal.add(Calendar.DAY_OF_WEEK, 1);
    }
    return workDays;
  }


  public void dateDiff(String startTime, String endTime, String format) {

    // 按照传入的格式生成一个simpledateformate对象
    SimpleDateFormat sd = new SimpleDateFormat(format);
    long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
    long nh = 1000 * 60 * 60;// 一小时的毫秒数
    long nm = 1000 * 60;// 一分钟的毫秒数
    long ns = 1000;// 一秒钟的毫秒数

    long diff;
    try {

      // 获得两个时间的毫秒时间差异

      diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();

      long day = diff / nd;// 计算差多少天

      long hour = diff % nd / nh;// 计算差多少小时

      long min = diff % nd % nh / nm;// 计算差多少分钟

      long sec = diff % nd % nh % nm / ns;// 计算差多少秒

      // 输出结果

      System.out.println("时间相差：" + day + "天" + hour + "小时" + min + "分钟" + sec + "秒。");

    } catch (ParseException e) {
      e.printStackTrace();
    }

  }

  public static void main(String[] args) {

    LogUtils.resetLogLevel(logger, org.slf4j.event.Level.INFO);
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
    try {

      //Calendar currentCal = Calendar.getInstance();
      //currentCal.setTime(sd.parse("2021-09-22"));
      //System.out.println("checkSpecitalCalendar:" + CalendarUtils.checkWorkDate(currentCal));
      System.out.println("calcWorkDays:"
          + CalendarUtils.calcWorkDays(sd.parse("2022-01-01"), sd.parse("2022-12-31")));

    } catch (ParseException e) {
      e.printStackTrace();
    }
  }
}
